﻿using System;

namespace autossl
{
    using Certificates = TencentCloud.Ssl.V20191205.Models.Certificates;
    using txcloud.sdk.SSL;
    using System.Text;
    using System.Threading;
    using System.IO;

    internal class CertTool
    {
        Certificates[] certificates;
        Certificate ctl;
        string fileauth_path;
        public CertTool(string fileauthPath)
        {
            ctl = new Certificate();
            certificates = ctl.ReadCertificates();
            this.fileauth_path = fileauthPath;
        }

        public void Clean()
        {
            Console.WriteLine("清理过期证书");
            foreach (var cert in certificates)
            {
                if (cert.Status == 3) // 已过期
                {
                    Console.WriteLine($"Delete cert: {cert.Domain}#{cert.CertificateId}");
                    ctl.DeleteCertificate(cert.CertificateId);
                    Console.WriteLine($"delete cert ok.");
                    continue;
                }
                if (cert.Status == 7 || cert.Status == 10) // 已取消，已吊销
                {
                    Console.WriteLine($"Delete cert: {cert.Domain}#{cert.CertificateId}");
                    ctl.DeleteCertificate(cert.CertificateId);
                    Console.WriteLine($"delete cert ok.");
                    continue;
                }

            }
        }

        public string ApplyNew(string domain)
        {
            Console.WriteLine($"ApplyCert Now uri certId: {domain}");
            var certId = ctl.ApplyCert(domain.Trim());
            Console.WriteLine($"Get certId: {certId}");
            return certId;
        }

        public void VerityCert(string certId)
        {
            Console.WriteLine($"Read Cert Now..");
            var cert = ctl.ReadCertificateDetail(certId);
            if (cert == null) return;
            if (cert.Status == 0)
            {
                if (cert.VerifyType != Certificate.DvAuthMethod_FILE)
                {
                    Console.WriteLine($"Change to FILE Verification");
                    ctl.ToFileCertVerification(certId);
                }

                Console.WriteLine($"Read FILE Verification");
                var fileauth_text = ctl.ReadFileAuth(certId);
                Console.WriteLine($"Write FILE Verification");
                if (File.Exists(fileauth_path)) File.Delete(fileauth_path);
                using (var fileauth = File.Create(fileauth_path))
                {
                    fileauth.Write(Encoding.ASCII.GetBytes(fileauth_text));
                    fileauth.Flush();
                }

                Console.WriteLine($"Write OK.");

                Console.WriteLine($"Start FILE Verification");
                int maxretry = 59;
                while (!ctl.CheckDomainLocalVerification(certId))
                {
                    Thread.Sleep(1000);
                    if (maxretry-- < 0)
                    {
                        Console.WriteLine("FILE Local Verification TIMEOUT");
                        return;
                    }
                }
                Console.WriteLine($"Local Verification OK.");
                Console.WriteLine($"Apply FILE Verification Ca");
                maxretry = 59;
                Console.WriteLine($"Start FILE Verification Ca");
                while (!ctl.CheckDomainVerification(certId))
                {
                    Thread.Sleep(1000);
                    if (maxretry-- < 0)
                    {
                        Console.WriteLine("FILE Ca Verification TIMEOUT");
                        return;
                    }
                }
                Console.WriteLine($"Ca Verification OK.");
                ctl.ApplyCertVerification(certId);
                Console.WriteLine($"Wait Cert..");

                maxretry = 128;
                while (ctl.ReadCertificateDetail(certId).Status != 1)
                {
                    Thread.Sleep(1000);
                    if (maxretry-- < 0)
                    {
                        Console.WriteLine("Cert Ca Verification TIMEOUT");
                        return;
                    }
                }
                Console.WriteLine($"Cert OK.");
            }
        }
    }
}
